<!DOCTYPE html>
<html lang="en">
  <head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
  <meta content="" name="keywords">

  <title> 杂技浅尝 - </title>
  <meta name="description" content="" />
  <meta property="og:title" content="杂技浅尝" />
  <meta name="twitter:title" content="杂技浅尝" />
  <meta name="author" content="{Description { .Site.Author.name }}"/>
  <meta name="twitter:card" content="summary" />
  <meta property="og:url" content="https://systemime.github.io/series/%E6%9D%82%E6%8A%80%E6%B5%85%E5%B0%9D/" />
  <meta property="og:type" content="website" />
  <meta property="og:site_name" content="听风的小站" />

  <meta name="generator" content="Hugo 0.67.0" />
  <link rel="canonical" href="https://systemime.github.io/series/%E6%9D%82%E6%8A%80%E6%B5%85%E5%B0%9D/" />
  <link rel="alternate" href="https://systemime.github.io/index.xml" type="application/rss+xml" title="听风的小站">
  <script src="https://res.cloudinary.com/jimmysong/raw/upload/rootsongjc-hugo/jquery-1.12.4.min.js"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.css" integrity="sha384-wITovz90syo1dJWVh32uuETPVEtGigN07tkttEqPv+uR2SE/mbQcG7ATL28aI9H0" crossorigin="anonymous">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  
  
  <link rel="stylesheet" href="https://systemime.github.io/css/main.css" />
  <link rel="stylesheet" href="https://systemime.github.io/css/my.css" />
  <link rel="stylesheet" href="https://systemime.github.io/css/pace.css" />
  <link rel="stylesheet" href="https://cdn.plyr.io/3.4.7/plyr.css">
  <link rel="stylesheet" href="https://systemime.github.io/css/lightgallery.css" />
  <link rel="stylesheet" href="https://systemime.github.io/css/baguetteBox.css" />
  <link rel="stylesheet" href="https://systemime.github.io/css/search.css" />
  <link rel="stylesheet" href="https://systemime.github.io/css/reward.css" />
  <link rel="stylesheet" href="https://systemime.github.io/css/share.min.css" />
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic" />
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" />
  <link rel="stylesheet" href="https://systemime.github.io/css/pygment_highlights.css" />
  <link rel="stylesheet" href="https://systemime.github.io/css/highlight.min.css" />
  <link rel="stylesheet" href="https://systemime.github.io/css/toc.css" />
  <link rel="stylesheet" href="https://systemime.github.io/css/lightbox.css" />
  <link rel="stylesheet" href="https://systemime.github.io/live2d/css/live2d.css" />
  
  <link href="https://systemime.github.io/css/video-js.css" rel="stylesheet">


<meta name="baidu-site-verification" content="g8IYR9SNLF" />
<script>
var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?cffe439e37449bb1c07ab26ab56484bb";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script>

<link rel="stylesheet" href="https://systemime.github.io/css/prism.css" />









<script src="https://systemime.github.io/js/pace.min.js" data-no-instant></script>



<script src="https://systemime.github.io/js/instantclick.min.js" data-no-instant></script>
   <script data-no-instant>
   InstantClick.on('change', function(isInitialLoad) {
     if (isInitialLoad === false) {
       if (typeof MathJax !== 'undefined') 
         MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
       if (typeof prettyPrint !== 'undefined') 
         prettyPrint();
       if (typeof _hmt !== 'undefined')  
         _hmt.push(['_trackPageview', location.pathname + location.search]);
       if (typeof ga !== 'undefined')  
           ga('send', 'pageview', location.pathname + location.search);
     }
   });
   InstantClick.init();
</script>




<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/gist-embed/2.7.1/gist-embed.min.js"></script>


<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<script>
  (adsbygoogle = window.adsbygoogle || []).push({
    google_ad_client: "ca-pub-3925981084585036",
    enable_page_level_ads: true
  });
</script>



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.1/photoswipe.min.css" integrity="sha256-sCl5PUOGMLfFYctzDW3MtRib0ctyUvI9Qsmq2wXOeBY=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.1/default-skin/default-skin.min.css" integrity="sha256-BFeI1V+Vh1Rk37wswuOYn5lsTcaU96hGaI7OUVCLjPc=" crossorigin="anonymous" />



<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">

<div class="pswp__bg"></div>

<div class="pswp__scroll-wrap">
    
    <div class="pswp__container">
      <div class="pswp__item"></div>
      <div class="pswp__item"></div>
      <div class="pswp__item"></div>
    </div>
    
    <div class="pswp__ui pswp__ui--hidden">
    <div class="pswp__top-bar">
      
      <div class="pswp__counter"></div>
      <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
      <button class="pswp__button pswp__button--share" title="Share"></button>
      <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
      <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
      
      
      <div class="pswp__preloader">
        <div class="pswp__preloader__icn">
          <div class="pswp__preloader__cut">
            <div class="pswp__preloader__donut"></div>
          </div>
        </div>
      </div>
    </div>
    <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
      <div class="pswp__share-tooltip"></div>
    </div>
    <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
    </button>
    <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
    </button>
    <div class="pswp__caption">
      <div class="pswp__caption__center"></div>
    </div>
    </div>
    </div>
</div>

</head>

  <body>
    <nav class="navbar navbar-default navbar-fixed-top navbar-custom">
  <div class="container-fluid">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#main-navbar">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="https://systemime.github.io">听风的小站</a>
    </div>
    <div class="collapse navbar-collapse" id="main-navbar">
      <ul class="nav navbar-nav navbar-right">
        
          
            <li>
		    <a title="博客" href="https://systemime.github.io/blog/">博客</a>
              
              
            </li>
          
        
          
            <li>
		    <a title="片刻" href="https://systemime.github.io/moment/">片刻</a>
              
              
            </li>
          
        
          
            <li>
		    <a title="关于" href="https://systemime.github.io/about/">关于</a>
              
              
            </li>
          
        
          
            <li>
		    <a title="留言" href="https://systemime.github.io/message/">留言</a>
              
              
            </li>
          
        

        

        
        
      </ul>
    </div>

    <div class="avatar-container">
      <div class="avatar-img-border">
        
      </div>
    </div>

  </div>
</nav>






    
  <header class="header-section ">
    <div class="intro-header no-img">
      <div class="container">
        <div class="row">
          <div class="col-lg-12 col-md-12 col-md-offset-0">
            <div class="page-heading">
              <h1>#杂技浅尝</h1>
              <hr class="small">
            </div>
          </div>
        </div>
      </div>
    </div>
  </header>

    
  <div class="container" role="main">
    <div class="row">
      <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
        
        <div class="posts-list">
          
            <article class="post-preview">
              <a href="https://systemime.github.io/blog/2019-02/docker%E6%93%8D%E4%BD%9C%E5%91%BD%E4%BB%A4%E5%9F%BA%E7%A1%80%E7%AF%87/">
                <h2 class="post-title">Docker操作命令——基础篇</h2>

                
              </a>

              <p class="post-meta">
                Posted on February 19, 2019
              </p>
              <div class="post-entry">
                
                  <h2 id="基本命令">基本命令</h2>
<h4 id="docker基本状态转换和容器相关图">docker基本状态转换和容器相关图</h4>
<p><img src="https://github.com/systemime/my_image/blob/master/Docker%E6%93%8D%E4%BD%9C%E5%91%BD%E4%BB%A4%E2%80%94%E2%80%94%E5%9F%BA%E6%9C%AC%E7%AF%87/%E7%8A%B6%E6%80%81%E8%BD%AC%E6%8D%A2%E5%92%8C%E5%91%BD%E4%BB%A4%E5%9B%BE.jpg?raw=true" alt="基本状态转换和容器相关图"></p>
<h4 id="拉取docker镜像">拉取docker镜像</h4>
<pre><code>docker pull image_name
</code></pre><h4 id="查看宿主机上的镜像docker镜像保存在varlibdocker目录下">查看宿主机上的镜像，Docker镜像保存在/var/lib/docker目录下:</h4>
<pre><code>docker images
</code></pre><h4 id="删除镜像">删除镜像</h4>
<pre><code>docker rmi docker.io/tomcat:7.0.77-jre7 或者 docker rmi b39c68b7af30
</code></pre><h4 id="查看当前有哪些容器正在运行">查看当前有哪些容器正在运行</h4>
<pre><code>docker ps
</code></pre><h4 id="查看所有容器">查看所有容器</h4>
<pre><code>docker ps -a
</code></pre><h4 id="运行docker镜像命令">运行Docker镜像命令</h4>
<pre><code># 交互式启动
docker run -it --rm ubuntu:18.04 bash

# 进入已经启动的容器内部
docker attach container_name/container_id

# 推荐的，进入已经启动的容器内部方法
docker exec -t -i CONTAINER_ID /bin/bash
</code></pre><p><code>docker run</code> 就是运行容器的命令，具体格式我们会在 <a href="../container">容器</a> 一节进行详细讲解，我们这里简要的说明一下上面用到的参数。</p>
<ul>
<li><code>-it</code>：这是两个参数，一个是 <code>-i</code>：交互式操作，一个是 <code>-t</code> 终端。我们这里打算进入 <code>bash</code> 执行一些命令并查看返回结果，因此我们需要交互式终端。</li>
<li><code>--rm</code>：这个参数是说容器退出后随之将其删除。默认情况下，为了排障需求，退出的容器并不会立即删除，除非手动 <code>docker rm</code>。我们这里只是随便执行个命令，看看结果，不需要排障和保留结果，因此使用 <code>--rm</code> 可以避免浪费空间。</li>
<li><code>ubuntu:18.04</code>：这是指用 <code>ubuntu:18.04</code> 镜像为基础来启动容器。</li>
<li><code>bash</code>：放在镜像名后的是<strong>命令</strong>，这里我们希望有个交互式 Shell，因此用的是 <code>bash</code>。</li>
</ul>
<p>进入容器后，我们可以在 Shell 下操作，执行任何所需的命令。这里，我们执行了 <code>cat /etc/os-release</code>，这是 Linux 常用的查看当前系统版本的命令，从返回的结果可以看到容器内是 <code>Ubuntu 18.04.1 LTS</code> 系统。</p>
<p>最后我们通过 <code>exit</code> 退出了这个容器。</p>
<p>** 若想要退出容器而不停止容器运行，请参阅本站《Docker——退出而不关闭容器》一文 **</p>
<h4 id="查看当前系统docker信息">查看当前系统Docker信息</h4>
<pre><code>docker info
</code></pre><h4 id="获取容器日志">获取容器日志</h4>
<pre><code>docker containers logs docker-name
# 或
docker logs docker-name
</code></pre>
                
              </div>

              
                <span class="post-meta">
                  
                    #<a href="https://systemime.github.iotags/docker/">Docker</a>&nbsp;
                  
                    #<a href="https://systemime.github.iotags/%E5%9F%BA%E7%A1%80/">基础</a>&nbsp;
                  
                    #<a href="https://systemime.github.iotags/%E6%93%8D%E4%BD%9C/">操作</a>&nbsp;
                  
                </span>
              

            </article>
          
            <article class="post-preview">
              <a href="https://systemime.github.io/blog/2019-02/docker%E9%80%80%E5%87%BA%E8%80%8C%E4%B8%8D%E5%85%B3%E9%97%AD%E5%AE%B9%E5%99%A8/">
                <h2 class="post-title">Docker——退出而不关闭容器</h2>

                
              </a>

              <p class="post-meta">
                Posted on February 19, 2019
              </p>
              <div class="post-entry">
                
                  <p>一般情况下，进入docker容器后如果退出容器，容器就会变成Exited的状态，那么如何退出容器让容器不关闭呢？</p>
<p>如果要正常退出不关闭容器，请按Ctrl+P+Q进行退出容器，这一点很重要，请牢记！</p>
<p>以下示例为退出容器但不关闭容器</p>
<pre><code>[root@localhost ~]# docker attach c600c4519fc8
[root@c600c4519fc8 /]# exit
exit
[root@localhost ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                    PORTS               NAMES
c600c4519fc8        centos              &quot;/bin/bash&quot;         3 hours ago         Exited (0) 1 second ago                       pensive_jackson
5a7a0d694651        busybox             &quot;sh&quot;                20 hours ago        Exited (0) 20 hours ago                       hungry_vaughan
4b0296d18849        hello-world         &quot;/hello&quot;            46 hours ago        Exited (0) 46 hours ago                       hopeful_yonath
[root@localhost ~]# docker start pensive_jackson
pensive_jackson
[root@localhost ~]# docker attach c600c4519fc8

Ctrl + P + Q 

[root@c600c4519fc8 /]# read escape sequence
[root@localhost ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                    PORTS               NAMES
c600c4519fc8        centos              &quot;/bin/bash&quot;         3 hours ago         Up 22 seconds                                 pensive_jackson
5a7a0d694651        busybox             &quot;sh&quot;                20 hours ago        Exited (0) 20 hours ago                       hungry_vaughan
4b0296d18849        hello-world         &quot;/hello&quot;            46 hours ago        Exited (0) 46 hours ago                       hopeful_yonath
</code></pre><p>事实上我们可以在启动容器的时候就进行配置，加入-d参数来启动容器，当然，这条命令仅限于启动全新的容器，启动关闭的容器是不可以的。</p>
<blockquote>
<p>Tips 1
docker run -d: 后台运行容器，并返回容器ID</p>
</blockquote>
<p>以下示例为使用docker -d启动容器并退出</p>
<pre><code>[root@localhost ~]# docker run -i -t -d centos /bin/bash
8521b11d5d99535d4cb0080adc5a58a4dd018ecd0751d9945f7da7ab01bec330
[root@localhost ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
8521b11d5d99        centos              &quot;/bin/bash&quot;         4 seconds ago       Up 4 seconds                                    eager_goldwasser
c600c4519fc8        centos              &quot;/bin/bash&quot;         3 hours ago         Exited (0) 28 seconds ago                       pensive_jackson
5a7a0d694651        busybox             &quot;sh&quot;                20 hours ago        Exited (0) 20 hours ago                         hungry_vaughan
4b0296d18849        hello-world         &quot;/hello&quot;            46 hours ago        Exited (0) 46 hours ago                         hopeful_yonath
[root@localhost ~]# docker attach 8
[root@8521b11d5d99 /]# uname -r
3.10.0-514.el7.x86_64
[root@8521b11d5d99 /]# exit
exit
[root@localhost ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
8521b11d5d99        centos              &quot;/bin/bash&quot;         2 minutes ago       Exited (0) 2 seconds ago                       eager_goldwasser
c600c4519fc8        centos              &quot;/bin/bash&quot;         3 hours ago         Exited (0) 2 minutes ago                       pensive_jackson
5a7a0d694651        busybox             &quot;sh&quot;                20 hours ago        Exited (0) 20 hours ago                        hungry_vaughan
4b0296d18849        hello-world         &quot;/hello&quot;            46 hours ago        Exited (0) 46 hours ago                        hopeful_yonath
</code></pre><p>在这里你可能会发现，使用了-d的命令退出后容器依然还是死了，动手型的朋友可能会发现只是用docker run -d去启动容器也一样是死的
这里其实需要了解的是容器的运行机制，Docker容器在后台运行，必须要有一个前台进程，这里我们让容器有前台程序运行，就可以实现容器的-d 启动后存活</p>
<pre><code>[root@localhost ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
c600c4519fc8        centos              &quot;/bin/bash&quot;         3 hours ago         Exited (0) 4 minutes ago                       pensive_jackson
5a7a0d694651        busybox             &quot;sh&quot;                21 hours ago        Exited (0) 21 hours ago                        hungry_vaughan
4b0296d18849        hello-world         &quot;/hello&quot;            47 hours ago        Exited (0) 47 hours ago                        hopeful_yonath
[root@localhost ~]# docker run -d centos /bin/bash -c &quot;nohup ping -i 1000 www.baidu.com&quot;
8aa19c9604382bc019797ccda831ae1bcebd81d86380b6040d636e03000b440a
[root@localhost ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
8aa19c960438        centos              &quot;/bin/bash -c 'nohup…&quot;   2 seconds ago       Up 2 seconds                                   adoring_wing
c600c4519fc8        centos              &quot;/bin/bash&quot;              3 hours ago         Exited (0) 5 minutes ago                       pensive_jackson
5a7a0d694651        busybox             &quot;sh&quot;                     21 hours ago        Exited (0) 21 hours ago                        hungry_vaughan
4b0296d18849        hello-world         &quot;/hello&quot;                 47 hours ago        Exited (0) 47 hours ago                        hopeful_yonath
</code></pre><p>我这里使用nohup在后台运行一个每1000秒ping一次百度的进程，另外你也可以使用&quot;while true; do echo hello world; sleep 1; done&rdquo;，无限输出hello world。</p>
<p>另外即便是有进程在后台运行，你进入了容器，输入exit退出，依然会终止容器的运行，请谨记。</p>
<p><strong>Ctrl+P+Q依然是我认为的最佳用法。</strong></p>

                
              </div>

              
                <span class="post-meta">
                  
                    #<a href="https://systemime.github.iotags/docker/">Docker</a>&nbsp;
                  
                    #<a href="https://systemime.github.iotags/%E9%80%80%E8%80%8C%E4%B8%8D%E5%85%B3/">退而不关</a>&nbsp;
                  
                </span>
              

            </article>
          
            <article class="post-preview">
              <a href="https://systemime.github.io/blog/2019-02/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E8%AF%A6%E8%A7%A3/">
                <h2 class="post-title">正则表达式详解</h2>

                
              </a>

              <p class="post-meta">
                Posted on February 17, 2019
              </p>
              <div class="post-entry">
                
                  <h2 id="什么是正则表达式-">什么是正则表达式 ？</h2>
<blockquote>
<p>正则表达式是一种被用于从文本中检索符合某些特定模式的文本。</p>
</blockquote>
<p>正则表达式是从左到右来匹配一个字符串的。&ldquo;Regular Expression&rdquo; 这个词太长了，我们通常使用它的缩写 &ldquo;regex&rdquo; 或者 &ldquo;regexp&rdquo;。
正则表达式可以被用来替换字符串中的文本、验证表单、基于模式匹配从一个字符串中提取字符串等等。
<!-- raw HTML omitted --></p>
<p>想象一下，您正在编写应用程序，并且您希望在用户选择用户名时设置规则。我们希望用户名可以包含字母，数字，下划线和连字符。
为了让它看起来不丑，我们还想限制用户名中的字符数量。我们可以使用以下正则表达式来验证用户名:</p>
<p><img src="https://i.imgur.com/UrDb9qc.png" alt="1">
上面这个正则表达式可以匹配 <code>john_doe</code>，<code>jo-hn\_doe</code> 和 <code>john12\_as</code>。但是它不能匹配 <code>Jo</code>，因为该字符串里面包含了大写字符，并且它太短了。</p>
<h2 id="目录">目录</h2>
<ul>
<li><a href="#1-%E5%9F%BA%E6%9C%AC%E5%8C%B9%E9%85%8D">基本匹配</a></li>
<li><a href="#2-%E5%85%83%E5%AD%97%E7%AC%A6">元字符</a>
<ul>
<li><a href="#21-%E8%8B%B1%E6%96%87%E5%8F%A5%E5%8F%B7">英文句号</a></li>
<li><a href="#22-%E5%AD%97%E7%AC%A6%E9%9B%86">字符集</a>
<ul>
<li><a href="#221-%E5%90%A6%E5%AE%9A%E5%AD%97%E7%AC%A6%E9%9B%86">否定字符集</a></li>
</ul>
</li>
<li><a href="#23-%E9%87%8D%E5%A4%8D">重复</a>
<ul>
<li><a href="#231-%E6%98%9F%E5%8F%B7">星号</a></li>
<li><a href="#232-%E5%8A%A0%E5%8F%B7">加号</a></li>
<li><a href="#233-%E9%97%AE%E5%8F%B7">问号</a></li>
</ul>
</li>
<li><a href="#24-%E8%8A%B1%E6%8B%AC%E5%8F%B7">花括号</a></li>
<li><a href="#25-%E5%AD%97%E7%AC%A6%E7%BB%84">字符组</a></li>
<li><a href="#26-%E5%88%86%E6%94%AF%E7%BB%93%E6%9E%84">分支结构</a></li>
<li><a href="#27-%E8%BD%AC%E4%B9%89%E7%89%B9%E6%AE%8A%E5%AD%97%E7%AC%A6">转义特殊字符</a></li>
<li><a href="#28-%E5%AE%9A%E4%BD%8D%E7%AC%A6">定位符</a>
<ul>
<li><a href="#281-%E6%8F%92%E5%85%A5%E7%AC%A6%E5%8F%B7">插入符号</a></li>
<li><a href="#282-%E7%BE%8E%E5%85%83%E7%AC%A6%E5%8F%B7">美元符号</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#3-%E7%AE%80%E5%86%99%E5%AD%97%E7%AC%A6%E9%9B%86">简写字符集</a></li>
<li><a href="#4-%E6%96%AD%E8%A8%80">断言</a>
<ul>
<li><a href="#41-%E6%AD%A3%E5%90%91%E5%85%88%E8%A1%8C%E6%96%AD%E8%A8%80">正向先行断言</a></li>
<li><a href="#42-%E8%B4%9F%E5%90%91%E5%85%88%E8%A1%8C%E6%96%AD%E8%A8%80">负向先行断言</a></li>
<li><a href="#43-%E6%AD%A3%E5%90%91%E5%90%8E%E8%A1%8C%E6%96%AD%E8%A8%80">正向后行断言</a></li>
<li><a href="#44-%E8%B4%9F%E5%90%91%E5%90%8E%E8%A1%8C%E6%96%AD%E8%A8%80">负向后行断言</a></li>
</ul>
</li>
<li><a href="#5-%E6%A0%87%E8%AE%B0">标记</a>
<ul>
<li><a href="#51-%E4%B8%8D%E5%8C%BA%E5%88%86%E5%A4%A7%E5%B0%8F%E5%86%99">不区分大小写</a></li>
<li><a href="#52-%E5%85%A8%E5%B1%80%E6%90%9C%E7%B4%A2">全局搜索</a></li>
<li><a href="#53-%E5%A4%9A%E8%A1%8C%E5%8C%B9%E9%85%8D">多行匹配</a></li>
</ul>
</li>
<li><a href="#%E5%B8%B8%E7%94%A8%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F">常用正则表达式</a></li>
</ul>
<h2 id="1-基本匹配">1. 基本匹配</h2>
<p>正则表达式只是我们用于在文本中检索字母和数字的模式。例如正则表达式 <code>cat</code>，表示: 字母 <code>c</code> 后面跟着一个字母 <code>a</code>，再后面跟着一个字母 <code>t</code>。</p>
<blockquote>
<p>&ldquo;cat&rdquo; =&gt; The <!-- raw HTML omitted --><!-- raw HTML omitted -->cat<!-- raw HTML omitted --><!-- raw HTML omitted --> sat on the mat</p>
</blockquote>
<p>正则表达式 <code>123</code> 会匹配字符串 &ldquo;123&rdquo;。通过将正则表达式中的每个字符逐个与要匹配的字符串中的每个字符进行比较，来完成正则匹配。
正则表达式通常区分大小写，因此正则表达式 <code>Cat</code> 与字符串 &ldquo;cat&rdquo; 不匹配。</p>
<blockquote>
<p>&ldquo;Cat&rdquo; =&gt; The cat sat on the <!-- raw HTML omitted --><!-- raw HTML omitted -->Cat<!-- raw HTML omitted --><!-- raw HTML omitted --></p>
</blockquote>
<h2 id="2-元字符">2. 元字符</h2>
<p>元字符是正则表达式的基本组成元素。元字符在这里跟它通常表达的意思不一样，而是以某种特殊的含义去解释。有些元字符写在方括号内的时候有特殊含义。
元字符如下:</p>
<table>
<thead>
<tr>
<th align="center">元字符</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">.</td>
<td>匹配除换行符以外的任意字符。</td>
</tr>
<tr>
<td align="center">[ ]</td>
<td>字符类，匹配方括号中包含的任意字符。</td>
</tr>
<tr>
<td align="center">[^ ]</td>
<td>否定字符类。匹配方括号中不包含的任意字符</td>
</tr>
<tr>
<td align="center">*</td>
<td>匹配前面的子表达式零次或多次</td>
</tr>
<tr>
<td align="center">+</td>
<td>匹配前面的子表达式一次或多次</td>
</tr>
<tr>
<td align="center">?</td>
<td>匹配前面的子表达式零次或一次，或指明一个非贪婪限定符。</td>
</tr>
<tr>
<td align="center">{n,m}</td>
<td>花括号，匹配前面字符至少 n 次，但是不超过 m 次。</td>
</tr>
<tr>
<td align="center">(xyz)</td>
<td>字符组，按照确切的顺序匹配字符xyz。</td>
</tr>
<tr>
<td align="center">|</td>
<td>分支结构，匹配符号之前的字符或后面的字符。</td>
</tr>
<tr>
<td align="center">\</td>
<td>转义符，它可以还原元字符原来的含义，允许你匹配保留字符 <!-- raw HTML omitted -->[ ] ( ) { } . * + ? ^ $ \ |<!-- raw HTML omitted --></td>
</tr>
<tr>
<td align="center">^</td>
<td>匹配行的开始</td>
</tr>
<tr>
<td align="center">$</td>
<td>匹配行的结束</td>
</tr>
</tbody>
</table>
<h2 id="21-英文句号">2.1 英文句号</h2>
<p>英文句号 <code>.</code> 是元字符的最简单的例子。元字符 <code>.</code> 可以匹配任意单个字符。它不会匹配换行符和新行的字符。例如正则表达式 <code>.ar</code>，表示: 任意字符后面跟着一个字母 <code>a</code>，
再后面跟着一个字母 <code>r</code>。</p>
<blockquote>
<p>&ldquo;.ar&rdquo; =&gt; The <!-- raw HTML omitted --><!-- raw HTML omitted -->car<!-- raw HTML omitted --><!-- raw HTML omitted --> <!-- raw HTML omitted --><!-- raw HTML omitted -->par<!-- raw HTML omitted --><!-- raw HTML omitted -->ked in the <!-- raw HTML omitted --><!-- raw HTML omitted -->gar<!-- raw HTML omitted --><!-- raw HTML omitted -->age.</p>
</blockquote>
<h2 id="22-字符集">2.2 字符集</h2>
<p>字符集也称为字符类。方括号被用于指定字符集。使用字符集内的连字符来指定字符范围。方括号内的字符范围的顺序并不重要。
例如正则表达式 <code>[Tt]he</code>，表示: 大写 <code>T</code> 或小写 <code>t</code> ，后跟字母 <code>h</code>，再后跟字母 <code>e</code>。</p>
<blockquote>
<p>&ldquo;[Tt]he&rdquo; =&gt; <!-- raw HTML omitted --><!-- raw HTML omitted -->The<!-- raw HTML omitted --><!-- raw HTML omitted --> car parked in <!-- raw HTML omitted --><!-- raw HTML omitted -->the<!-- raw HTML omitted --><!-- raw HTML omitted --> garage.</p>
</blockquote>
<p>然而，字符集中的英文句号表示它字面的含义。正则表达式 <code>ar[.]</code>，表示小写字母 <code>a</code>，后面跟着一个字母 <code>r</code>，再后面跟着一个英文句号 <code>.</code> 字符。</p>
<blockquote>
<p>&ldquo;ar[.]&rdquo; =&gt; A garage is a good place to park a c<!-- raw HTML omitted --><!-- raw HTML omitted -->ar.<!-- raw HTML omitted --><!-- raw HTML omitted --></p>
</blockquote>
<h3 id="221-否定字符集">2.2.1 否定字符集</h3>
<p>一般来说插入字符 <code>^</code> 表示一个字符串的开始，但是当它在方括号内出现时，它会取消字符集。例如正则表达式 <code>[^c]ar</code>，表示: 除了字母 <code>c</code> 以外的任意字符，后面跟着字符 <code>a</code>，
再后面跟着一个字母 <code>r</code>。</p>
<blockquote>
<p>&ldquo;[^c]ar&rdquo; =&gt; The car <!-- raw HTML omitted --><!-- raw HTML omitted -->par<!-- raw HTML omitted --><!-- raw HTML omitted -->ked in the <!-- raw HTML omitted --><!-- raw HTML omitted -->gar<!-- raw HTML omitted --><!-- raw HTML omitted -->age.</p>
</blockquote>
<h2 id="23-重复">2.3 重复</h2>
<p>以下元字符 <code>+</code>，<code>*</code> 或 <code>?</code> 用于指定子模式可以出现多少次。这些元字符在不同情况下的作用不同。</p>
<h3 id="231-星号">2.3.1 星号</h3>
<p>该符号 <code>*</code> 表示匹配上一个匹配规则的零次或多次。正则表达式 <code>a*</code> 表示小写字母 <code>a</code> 可以重复零次或者多次。但是它如果出现在字符集或者字符类之后，它表示整个字符集的重复。
例如正则表达式 <code>[a-z]*</code>，表示: 一行中可以包含任意数量的小写字母。</p>
<blockquote>
<p>&rdquo;[a-z]*&rdquo; =&gt; T<!-- raw HTML omitted --><!-- raw HTML omitted -->he<!-- raw HTML omitted --><!-- raw HTML omitted --> <!-- raw HTML omitted --><!-- raw HTML omitted -->car<!-- raw HTML omitted --><!-- raw HTML omitted --> <!-- raw HTML omitted --><!-- raw HTML omitted -->parked<!-- raw HTML omitted --><!-- raw HTML omitted --> <!-- raw HTML omitted --><!-- raw HTML omitted -->in<!-- raw HTML omitted --><!-- raw HTML omitted --> <!-- raw HTML omitted --><!-- raw HTML omitted -->the<!-- raw HTML omitted --><!-- raw HTML omitted --> <!-- raw HTML omitted --><!-- raw HTML omitted -->garage<!-- raw HTML omitted --><!-- raw HTML omitted --> #21.</p>
</blockquote>
<p>该 <code>*</code> 符号可以与元符号 <code>.</code> 用在一起，用来匹配任意字符串 <code>.*</code>。该 <code>*</code> 符号可以与空格符 <code>\s</code> 一起使用，用来匹配一串空格字符。
例如正则表达式 <code>\s*cat\s*</code>，表示: 零个或多个空格，后面跟小写字母 <code>c</code>，再后面跟小写字母 <code>a</code>，再再后面跟小写字母 <code>t</code>，后面再跟零个或多个空格。</p>
<blockquote>
<p>&ldquo;\s<em>cat\s</em>&rdquo; =&gt; The fat<!-- raw HTML omitted --><!-- raw HTML omitted --> cat <!-- raw HTML omitted --><!-- raw HTML omitted -->sat on the <!-- raw HTML omitted --><!-- raw HTML omitted -->cat<!-- raw HTML omitted --><!-- raw HTML omitted -->.</p>
</blockquote>
<h3 id="232-加号">2.3.2 加号</h3>
<p>该符号 <code>+</code> 匹配上一个字符的一次或多次。例如正则表达式 <code>c.+t</code>，表示: 一个小写字母 <code>c</code>，后跟任意数量的字符，后跟小写字母 <code>t</code>。</p>
<blockquote>
<p>&ldquo;c.+t&rdquo; =&gt; The fat <!-- raw HTML omitted --><!-- raw HTML omitted -->cat sat on the mat<!-- raw HTML omitted --><!-- raw HTML omitted -->.</p>
</blockquote>
<h3 id="233-问号">2.3.3 问号</h3>
<p>在正则表达式中，元字符 <code>?</code> 用来表示前一个字符是可选的。该符号匹配前一个字符的零次或一次。
例如正则表达式 <code>[T]?he</code>，表示: 可选的大写字母 <code>T</code>，后面跟小写字母 <code>h</code>，后跟小写字母 <code>e</code>。</p>
<blockquote>
<p>&ldquo;[T]he&rdquo; =&gt; <!-- raw HTML omitted --><!-- raw HTML omitted -->The<!-- raw HTML omitted --><!-- raw HTML omitted --> car is parked in the garage.</p>
</blockquote>
<blockquote>
<p>&ldquo;[T]?he&rdquo; =&gt; <!-- raw HTML omitted --><!-- raw HTML omitted -->The<!-- raw HTML omitted --><!-- raw HTML omitted --> car is parked in t<!-- raw HTML omitted --><!-- raw HTML omitted -->he<!-- raw HTML omitted --><!-- raw HTML omitted --> garage.</p>
</blockquote>
<h2 id="24-花括号">2.4 花括号</h2>
<p>在正则表达式中花括号(也被称为量词 ?)用于指定字符或一组字符可以重复的次数。例如正则表达式 <code>[0-9]{2,3}</code>，表示: 匹配至少2位数字但不超过3位(0到9范围内的字符)。</p>
<blockquote>
<p>&ldquo;[0-9]{2,3}&rdquo; =&gt; The number was 9.<!-- raw HTML omitted --><!-- raw HTML omitted -->999<!-- raw HTML omitted --><!-- raw HTML omitted -->7 but we rounded it off to <!-- raw HTML omitted --><!-- raw HTML omitted -->10<!-- raw HTML omitted --><!-- raw HTML omitted -->.0.</p>
</blockquote>
<p>我们可以省略第二个数字。例如正则表达式 <code>[0-9]{2,}</code>，表示: 匹配2个或更多个数字。如果我们也删除逗号，则正则表达式 <code>[0-9]{2}</code>，表示: 匹配正好为2位数的数字。</p>
<blockquote>
<p>&ldquo;[0-9]{2,}&rdquo; =&gt; The number was 9.<!-- raw HTML omitted --><!-- raw HTML omitted -->9997<!-- raw HTML omitted --><!-- raw HTML omitted --> but we rounded it off to <!-- raw HTML omitted --><!-- raw HTML omitted -->10<!-- raw HTML omitted --><!-- raw HTML omitted -->.0.</p>
</blockquote>
<blockquote>
<p>&ldquo;[0-9]{2}&rdquo; =&gt; The number was 9.<!-- raw HTML omitted --><!-- raw HTML omitted -->99<!-- raw HTML omitted --><!-- raw HTML omitted --><!-- raw HTML omitted --><!-- raw HTML omitted -->97<!-- raw HTML omitted --><!-- raw HTML omitted --> but we rounded it off to <!-- raw HTML omitted --><!-- raw HTML omitted -->10<!-- raw HTML omitted --><!-- raw HTML omitted -->.0.</p>
</blockquote>
<h2 id="25-字符组">2.5 字符组</h2>
<p>字符组是一组写在圆括号内的子模式 <code>(...)</code>。正如我们在正则表达式中讨论的那样，如果我们把一个量词放在一个字符之后，它会重复前一个字符。
但是，如果我们把量词放在一个字符组之后，它会重复整个字符组。
例如正则表达式 <code>(ab)*</code> 表示匹配零个或多个的字符串 &ldquo;ab&rdquo;。我们还可以在字符组中使用元字符 <code>|</code>。例如正则表达式 <code>(c|g|p)ar</code>，表示: 小写字母 <code>c</code>、<code>g</code> 或 <code>p</code> 后面跟字母 <code>a</code>，后跟字母 <code>r</code>。</p>
<blockquote>
<p>&ldquo;(c|g|p)ar&rdquo; =&gt; The <!-- raw HTML omitted --><!-- raw HTML omitted -->car<!-- raw HTML omitted --><!-- raw HTML omitted --> is <!-- raw HTML omitted --><!-- raw HTML omitted -->par<!-- raw HTML omitted --><!-- raw HTML omitted -->ked in the <!-- raw HTML omitted --><!-- raw HTML omitted -->gar<!-- raw HTML omitted --><!-- raw HTML omitted -->age.</p>
</blockquote>
<h2 id="26-分支结构">2.6 分支结构</h2>
<p>在正则表达式中垂直条 <code>|</code> 用来定义分支结构，分支结构就像多个表达式之间的条件。现在你可能认为这个字符集和分支机构的工作方式一样。
但是字符集和分支结构巨大的区别是字符集只在字符级别上有作用，然而分支结构在表达式级别上依然可以使用。
例如正则表达式 <code>(T|t)he|car</code>，表示: 大写字母 <code>T</code> 或小写字母 <code>t</code>，后面跟小写字母 <code>h</code>，后跟小写字母 <code>e</code> 或小写字母 <code>c</code>，后跟小写字母 <code>a</code>，后跟小写字母 <code>r</code>。</p>
<blockquote>
<p>&ldquo;(T|t)he|car&rdquo; =&gt; <!-- raw HTML omitted --><!-- raw HTML omitted -->The<!-- raw HTML omitted --><!-- raw HTML omitted --> <!-- raw HTML omitted --><!-- raw HTML omitted -->car<!-- raw HTML omitted --><!-- raw HTML omitted --> is parked in <!-- raw HTML omitted --><!-- raw HTML omitted -->the<!-- raw HTML omitted --><!-- raw HTML omitted --> garage.</p>
</blockquote>
<h2 id="27-转义特殊字符">2.7 转义特殊字符</h2>
<p>正则表达式中使用反斜杠 <code>\</code> 来转义下一个字符。这将允许你使用保留字符来作为匹配字符 <code>{ } [ ] / \ + * . $ ^ | ?</code>。在特殊字符前面加 <code>\</code>，就可以使用它来做匹配字符。
例如正则表达式 <code>.</code> 是用来匹配除了换行符以外的任意字符。现在要在输入字符串中匹配 <code>.</code> 字符，正则表达式 <code>(f|c|m)at\.?</code>，表示: 小写字母 <code>f</code>、<code>c</code> 或者 <code>m</code> 后跟小写字母 <code>a</code>，后跟小写字母 <code>t</code>，后跟可选的 <code>.</code> 字符。</p>
<blockquote>
<p>&ldquo;(f|c|m)at.?&rdquo; =&gt; The <!-- raw HTML omitted --><!-- raw HTML omitted -->fat<!-- raw HTML omitted --><!-- raw HTML omitted --> <!-- raw HTML omitted --><!-- raw HTML omitted -->cat<!-- raw HTML omitted --><!-- raw HTML omitted --> sat on the <!-- raw HTML omitted --><!-- raw HTML omitted -->mat.<!-- raw HTML omitted --><!-- raw HTML omitted --></p>
</blockquote>
<h2 id="28-定位符">2.8 定位符</h2>
<p>在正则表达式中，为了检查匹配符号是否是起始符号或结尾符号，我们使用定位符。
定位符有两种类型: 第一种类型是 <code>^</code> 检查匹配字符是否是起始字符，第二种类型是 <code>$</code>，它检查匹配字符是否是输入字符串的最后一个字符。</p>
<h3 id="281-插入符号">2.8.1 插入符号</h3>
<p>插入符号 <code>^</code> 符号用于检查匹配字符是否是输入字符串的第一个字符。如果我们使用正则表达式 <code>^a</code> (如果a是起始符号)匹配字符串 <code>abc</code>，它会匹配到 <code>a</code>。
但是如果我们使用正则表达式 <code>^b</code>，它是匹配不到任何东西的，因为在字符串 <code>abc</code> 中 &ldquo;b&rdquo; 不是起始字符。
让我们来看看另一个正则表达式 <code>^(T|t)he</code>，这表示: 大写字母 <code>T</code> 或小写字母 <code>t</code> 是输入字符串的起始符号，后面跟着小写字母 <code>h</code>，后跟小写字母 <code>e</code>。</p>
<blockquote>
<p>&ldquo;(T|t)he&rdquo; =&gt; <!-- raw HTML omitted --><!-- raw HTML omitted -->The<!-- raw HTML omitted --><!-- raw HTML omitted --> car is parked in <!-- raw HTML omitted --><!-- raw HTML omitted -->the<!-- raw HTML omitted --><!-- raw HTML omitted --> garage.</p>
</blockquote>
<blockquote>
<p>&ldquo;^(T|t)he&rdquo; =&gt; <!-- raw HTML omitted --><!-- raw HTML omitted -->The<!-- raw HTML omitted --><!-- raw HTML omitted --> car is parked in the garage.</p>
</blockquote>
<h3 id="282-美元符号">2.8.2 美元符号</h3>
<p>美元 <code>$</code> 符号用于检查匹配字符是否是输入字符串的最后一个字符。例如正则表达式 <code>(at\.)$</code>，表示: 小写字母 <code>a</code>，后跟小写字母 <code>t</code>，后跟一个 <code>.</code> 字符，且这个匹配器必须是字符串的结尾。</p>
<blockquote>
<p>&ldquo;(at.)&rdquo; =&gt; The fat c<!-- raw HTML omitted --><!-- raw HTML omitted -->at.<!-- raw HTML omitted --><!-- raw HTML omitted --> s<!-- raw HTML omitted --><!-- raw HTML omitted -->at.<!-- raw HTML omitted --><!-- raw HTML omitted --> on the m<!-- raw HTML omitted --><!-- raw HTML omitted -->at.<!-- raw HTML omitted --><!-- raw HTML omitted --></p>
</blockquote>
<blockquote>
<p>&ldquo;(at.)$&rdquo; =&gt; The fat cat sat on the m<!-- raw HTML omitted --><!-- raw HTML omitted -->at.<!-- raw HTML omitted --><!-- raw HTML omitted --></p>
</blockquote>
<h2 id="3-简写字符集">3. 简写字符集</h2>
<p>正则表达式为常用的字符集和常用的正则表达式提供了简写。简写字符集如下:</p>
<table>
<thead>
<tr>
<th align="center">简写</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">.</td>
<td>匹配除换行符以外的任意字符</td>
</tr>
<tr>
<td align="center">\w</td>
<td>匹配所有字母和数字的字符: <code>[a-zA-Z0-9_]</code></td>
</tr>
<tr>
<td align="center">\W</td>
<td>匹配非字母和数字的字符: <code>[^\w]</code></td>
</tr>
<tr>
<td align="center">\d</td>
<td>匹配数字: <code>[0-9]</code></td>
</tr>
<tr>
<td align="center">\D</td>
<td>匹配非数字: <code>[^\d]</code></td>
</tr>
<tr>
<td align="center">\s</td>
<td>匹配空格符: <code>[\t\n\f\r\p{Z}]</code></td>
</tr>
<tr>
<td align="center">\S</td>
<td>匹配非空格符: <code>[^\s]</code></td>
</tr>
</tbody>
</table>
<h2 id="4-断言">4. 断言</h2>
<p>后行断言和先行断言有时候被称为断言，它们是特殊类型的 <em><strong>非捕获组</strong></em> (用于匹配模式，但不包括在匹配列表中)。当我们在一种特定模式之前或者之后有这种模式时，会优先使用断言。
例如我们想获取输入字符串 <code>$4.44 and $10.88</code> 中 <code>$</code> 字符之前的所有数字。我们可以使用这个正则表达式 <code>(?&lt;=\$)[0-9\.]*</code>，表示: 获取 <code>$</code> 字符之前的所有的数字包含 <code>.</code> 字符。
以下是正则表达式中使用的断言:</p>
<table>
<thead>
<tr>
<th align="center">符号</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">?=</td>
<td>正向先行断言</td>
</tr>
<tr>
<td align="center">?!</td>
<td>负向先行断言</td>
</tr>
<tr>
<td align="center">?&lt;=</td>
<td>正向后行断言</td>
</tr>
<tr>
<td align="center">?&lt;!</td>
<td>负向后行断言</td>
</tr>
</tbody>
</table>
<h3 id="41-正向先行断言">4.1 正向先行断言</h3>
<p>正向先行断言认为第一部分的表达式必须是先行断言表达式。返回的匹配结果仅包含与第一部分表达式匹配的文本。
要在一个括号内定义一个正向先行断言，在括号中问号和等号是这样使用的 <code>(?=...)</code>。先行断言表达式写在括号中的等号后面。
例如正则表达式 <code>(T|t)he(?=\sfat)</code>，表示: 匹配大写字母 <code>T</code> 或小写字母 <code>t</code>，后面跟字母 <code>h</code>，后跟字母 <code>e</code>。
在括号中，我们定义了正向先行断言，它会引导正则表达式引擎匹配 <code>The</code> 或 <code>the</code> 后面跟着 <code>fat</code>。</p>
<blockquote>
<p>&ldquo;(T|t)he(?=\sfat)&rdquo; =&gt; <!-- raw HTML omitted --><!-- raw HTML omitted -->The<!-- raw HTML omitted --><!-- raw HTML omitted --> fat cat sat on the mat.</p>
</blockquote>
<h3 id="42-负向先行断言">4.2 负向先行断言</h3>
<p>当我们需要从输入字符串中获取不匹配表达式的内容时，使用负向先行断言。负向先行断言的定义跟我们定义的正向先行断言一样，
唯一的区别是不是等号 <code>=</code>，我们使用否定符号 <code>!</code>，例如 <code>(?!...)</code>。
我们来看看下面的正则表达式 <code>(T|t)he(?!\sfat)</code>，表示: 从输入字符串中获取全部 <code>The</code> 或者 <code>the</code> 且不匹配 <code>fat</code> 前面加上一个空格字符。</p>
<blockquote>
<p>&ldquo;(T|t)he(?!\sfat)&rdquo; =&gt; The fat cat sat on <!-- raw HTML omitted --><!-- raw HTML omitted -->the<!-- raw HTML omitted --><!-- raw HTML omitted --> mat.</p>
</blockquote>
<h3 id="43-正向后行断言">4.3 正向后行断言</h3>
<p>正向后行断言是用于获取在特定模式之前的所有匹配内容。正向后行断言表示为 <code>(?&lt;=...)</code>。例如正则表达式 <code>(?&lt;=(T|t)he\s)(fat|mat)</code>，表示: 从输入字符串中获取在单词 <code>The</code> 或 <code>the</code> 之后的所有 <code>fat</code> 和 <code>mat</code> 单词。</p>
<blockquote>
<p>&ldquo;(?&lt;=(T|t)he\s)(fat|mat)&rdquo; =&gt; The <!-- raw HTML omitted --><!-- raw HTML omitted -->fat<!-- raw HTML omitted --><!-- raw HTML omitted --> cat sat on the <!-- raw HTML omitted --><!-- raw HTML omitted -->mat<!-- raw HTML omitted --><!-- raw HTML omitted -->.</p>
</blockquote>
<h3 id="44-负向后行断言">4.4 负向后行断言</h3>
<p>负向后行断言是用于获取不在特定模式之前的所有匹配的内容。负向后行断言表示为 <code>(?&lt;!...)</code>。例如正则表达式 <code>(?&lt;!(T|t)he\s)(cat)</code>，表示: 在输入字符中获取所有不在 <code>The</code> 或 <code>the</code> 之后的所有单词 <code>cat</code>。</p>
<blockquote>
<p>&ldquo;(?&lt;!(T|t)he\s)(cat)&rdquo; =&gt; The cat sat on <!-- raw HTML omitted --><!-- raw HTML omitted -->cat<!-- raw HTML omitted --><!-- raw HTML omitted -->.</p>
</blockquote>
<h2 id="5-标记">5. 标记</h2>
<p>标记也称为修饰符，因为它会修改正则表达式的输出。这些标志可以以任意顺序或组合使用，并且是正则表达式的一部分。</p>
<table>
<thead>
<tr>
<th align="center">标记</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">i</td>
<td>不区分大小写: 将匹配设置为不区分大小写。</td>
</tr>
<tr>
<td align="center">g</td>
<td>全局搜索: 搜索整个输入字符串中的所有匹配。</td>
</tr>
<tr>
<td align="center">m</td>
<td>多行匹配: 会匹配输入字符串每一行。</td>
</tr>
</tbody>
</table>
<h3 id="51-不区分大小写">5.1 不区分大小写</h3>
<p><code>i</code> 修饰符用于执行不区分大小写匹配。例如正则表达式 <code>/The/gi</code>，表示: 大写字母 <code>T</code>，后跟小写字母 <code>h</code>，后跟字母 <code>e</code>。
但是在正则匹配结束时 <code>i</code> 标记会告诉正则表达式引擎忽略这种情况。正如你所看到的，我们还使用了 <code>g</code> 标记，因为我们要在整个输入字符串中搜索匹配。</p>
<blockquote>
<p>&ldquo;The&rdquo; =&gt; <!-- raw HTML omitted --><!-- raw HTML omitted -->The<!-- raw HTML omitted --><!-- raw HTML omitted --> fat cat sat on the mat.</p>
</blockquote>
<blockquote>
<p>&ldquo;/The/gi&rdquo; =&gt; <!-- raw HTML omitted --><!-- raw HTML omitted -->The<!-- raw HTML omitted --><!-- raw HTML omitted --> fat cat sat on <!-- raw HTML omitted --><!-- raw HTML omitted -->the<!-- raw HTML omitted --><!-- raw HTML omitted --> mat.</p>
</blockquote>
<h3 id="52-全局搜索">5.2 全局搜索</h3>
<p><code>g</code> 修饰符用于执行全局匹配 (会查找所有匹配，不会在查找到第一个匹配时就停止)。
例如正则表达式 <code>/.(at)/g</code>，表示: 除换行符之外的任意字符，后跟小写字母 <code>a</code>，后跟小写字母 <code>t</code>。
因为我们在正则表达式的末尾使用了 <code>g</code> 标记，它会从整个输入字符串中找到每个匹配项。</p>
<blockquote>
<p>&ldquo;.(at)&rdquo; =&gt; The <!-- raw HTML omitted --><!-- raw HTML omitted -->fat<!-- raw HTML omitted --><!-- raw HTML omitted --> cat sat on the mat.</p>
</blockquote>
<blockquote>
<p>&ldquo;/.(at)/g&rdquo; =&gt; The <!-- raw HTML omitted --><!-- raw HTML omitted -->fat<!-- raw HTML omitted --><!-- raw HTML omitted --> <!-- raw HTML omitted --><!-- raw HTML omitted -->cat<!-- raw HTML omitted --><!-- raw HTML omitted --> <!-- raw HTML omitted --><!-- raw HTML omitted -->sat<!-- raw HTML omitted --><!-- raw HTML omitted --> on the <!-- raw HTML omitted --><!-- raw HTML omitted -->mat<!-- raw HTML omitted --><!-- raw HTML omitted -->.</p>
</blockquote>
<h3 id="53-多行匹配">5.3 多行匹配</h3>
<p><code>m</code> 修饰符被用来执行多行的匹配。正如我们前面讨论过的 <code>(^, $)</code>，使用定位符来检查匹配字符是输入字符串开始或者结束。但是我们希望每一行都使用定位符，所以我们就使用 <code>m</code> 修饰符。
例如正则表达式 <code>/at(.)?$/gm</code>，表示: 小写字母 <code>a</code>，后跟小写字母 <code>t</code>，匹配除了换行符以外任意字符零次或一次。而且因为 <code>m</code> 标记，现在正则表达式引擎匹配字符串中每一行的末尾。</p>
<blockquote>
<p>&ldquo;/.at(.)?$/&rdquo; =&gt; The fat
cat sat
on the <!-- raw HTML omitted --><!-- raw HTML omitted -->mat.<!-- raw HTML omitted --><!-- raw HTML omitted --></p>
</blockquote>
<blockquote>
<p>&ldquo;/.at(.)?$/gm&rdquo; =&gt; The <!-- raw HTML omitted --><!-- raw HTML omitted -->fat<!-- raw HTML omitted --><!-- raw HTML omitted -->
cat <!-- raw HTML omitted --><!-- raw HTML omitted -->sat<!-- raw HTML omitted --><!-- raw HTML omitted -->
on the <!-- raw HTML omitted --><!-- raw HTML omitted -->mat.<!-- raw HTML omitted --><!-- raw HTML omitted --></p>
</blockquote>
<h2 id="常用正则表达式">常用正则表达式</h2>
<ul>
<li><strong>正整数</strong>: <code>^\d+$</code></li>
<li><strong>负整数</strong>: <code>^-\d+$</code></li>
<li><strong>电话号码</strong>: <code>^+?[\d\s]{3,}$</code></li>
<li><strong>电话代码</strong>: <code>^+?[\d\s]+(?[\d\s]{10,}$</code></li>
<li><strong>整数</strong>: <code>^-?\d+$</code></li>
<li><strong>用户名</strong>: <code>^[\w\d_.]{4,16}$</code></li>
<li><strong>字母数字字符</strong>: <code>^[a-zA-Z0-9]*$</code></li>
<li><strong>带空格的字母数字字符</strong>: <code>^[a-zA-Z0-9 ]*$</code></li>
<li><strong>密码</strong>: <code>^(?=^.{6,}$)((?=.*[A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z]))^.*$</code></li>
<li><strong>电子邮件</strong>: <code>^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4})*$</code></li>
<li><strong>IPv4 地址</strong>: <code>^((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))*$</code></li>
<li><strong>小写字母</strong>: <code>^([a-z])*$</code></li>
<li><strong>大写字母</strong>: <code>^([A-Z])*$</code></li>
<li><strong>网址</strong>: <code>^(((http|https|ftp):\/\/)?([[a-zA-Z0-9]\-\.])+(\.)([[a-zA-Z0-9]]){2,4}([[a-zA-Z0-9]\/+=%&amp;_\.~?\-]*))*$</code></li>
<li><strong>VISA 信用卡号码</strong>: <code>^(4[0-9]{12}(?:[0-9]{3})?)*$</code></li>
<li><strong>日期 (MM/DD/YYYY)</strong>: <code>^(0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])[- /.](19|20)?[0-9]{2}$</code></li>
<li><strong>日期 (YYYY/MM/DD)</strong>: <code>^(19|20)?[0-9]{2}[- /.](0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])$</code></li>
<li><strong>万事达信用卡号码</strong>: <code>^(5[1-5][0-9]{14})*$</code></li>
</ul>
<h2 id="contribution">Contribution</h2>
<ul>
<li>Report issues</li>
<li>Open pull request with improvements</li>
<li>Spread the word</li>
</ul>

                
              </div>

              
                <span class="post-meta">
                  
                    #<a href="https://systemime.github.iotags/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/">正则表达式</a>&nbsp;
                  
                </span>
              

            </article>
          
            <article class="post-preview">
              <a href="https://systemime.github.io/blog/2019-02/linux%E8%BF%90%E7%BB%B4%E5%9F%BA%E6%9C%AC%E5%8A%9F-xargs/">
                <h2 class="post-title">linux运维基本功 xargs</h2>

                
              </a>

              <p class="post-meta">
                Posted on February 16, 2019
              </p>
              <div class="post-entry">
                
                  <h1 id="linux运维基本功-xargs">Linux运维基本功 xargs</h1>
<p>xargs命令是给其他命令传递参数的一个过滤器，也是组合多个命令的一个工具。它擅长将标准输入数据转换成命令行参数，xargs能够处理管道或者stdin并将其转换成特定命令的命令参数。xargs也可以将单行或多行文本输入转换为其他格式，例如多行变单行，单行变多行。xargs的默认命令是echo，空格是默认定界符。这意味着通过管道传递给xargs的输入将会包含换行和空白，不过通过xargs的处理，换行和空白将被空格取代。xargs是构建单行命令的重要组件之一。</p>
<h2 id="xargs命令用法"><code>xargs</code>命令用法</h2>
<p>xargs用作替换工具，读取输入数据重新格式化后输出。
定义一个测试文件，内有多行文本数据：</p>
<pre><code> cat test.txt

 a b c d e f g
 h i j k l m n
 o p q
 r s t
 u v w x y z
</code></pre><p>多行输入单行输出：</p>
<pre><code>cat test.txt | xargs

 a b c d e f g h i j k l m n o p q r s t u v w x y z
</code></pre><p><strong><code>-n选项</code></strong>多行输出：</p>
<pre><code> cat test.txt | xargs -n3

 a b c
 d e f
 g h i
 j k l
 m n o
 p q r
 s t u
 v w x
 y z
</code></pre><p><strong><code>-d选项</code></strong>可以自定义一个定界符：</p>
<pre><code> echo &quot;nameXnameXnameXname&quot; | xargs -dX

 name name name name
</code></pre><p>结合<strong><code>-n选项</code></strong>使用：</p>
<pre><code> echo &quot;nameXnameXnameXname&quot; | xargs -dX -n2

 name name
 name name
</code></pre><p><strong>读取stdin，将格式化后的参数传递给命令</strong></p>
<p>假设一个命令为 sk.sh 和一个保存参数的文件arg.txt：</p>
<pre><code> #!/bin/bash
 #sk.sh命令内容，打印出所有参数。
 
 echo $*
</code></pre><p>arg.txt文件内容：</p>
<pre><code> cat arg.txt

 aaa
 bbb
 ccc
</code></pre><p>xargs的一个<code>选项-I</code>，使用-I指定一个<code>替换字符串{}</code>，这个字符串在xargs扩展时会被替换掉，当-I与xargs结合使用，每一个参数命令都会被执行一次：</p>
<pre><code> cat arg.txt | xargs -I {} ./sk.sh -p {} -l

 -p aaa -l
 -p bbb -l
 -p ccc -l
</code></pre><p>复制所有图片文件到 /data/images 目录下：</p>
<pre><code>ls *.jpg | xargs -n1 -I cp {} /data/images
</code></pre><p><strong>xargs结合find使用</strong>
用<code>rm </code>删除太多的文件时候，可能得到一个错误信息：<code>/bin/rm Argument list too long.</code> 用<code>xargs</code>去避免这个问题：</p>
<pre><code> find . -type f -name &quot;*.log&quot; -print0 | xargs -0 rm -f
</code></pre><p>xargs -0将\0作为定界符。</p>
<pre><code># 统计一个源代码目录中所有php文件的行数：
find . -type f -name &quot;*.php&quot; -print0 | xargs -0 wc -l

# 查找所有的jpg 文件，并且压缩它们：
find . -type f -name &quot;*.jpg&quot; -print | xargs tar -czvf images.tar.gz
</code></pre><p><strong>xargs其他应用</strong></p>
<p>假如你有一个文件包含了很多你希望下载的URL，你能够使用xargs下载所有链接：</p>
<pre><code>cat url-list.txt | xargs wget -c
</code></pre><h2 id="子shellsubshells">子Shell（Subshells）</h2>
<p>运行一个shell脚本时会启动另一个命令解释器.，就好像你的命令是在命令行提示下被解释的一样，类似于批处理文件里的一系列命令。每个shell脚本有效地运行在父shell(parent shell)的一个子进程里。这个父shell是指在一个控制终端或在一个xterm窗口中给你命令指示符的进程。</p>
<pre><code>cmd1 | ( cmd2; cmd3; cmd4 ) | cmd5
</code></pre><p>如果 cmd2 是 cd /，那么就会改变子Shell的工作目录，这种改变只是局限于子shell内部，cmd5 则完全不知道工作目录发生的变化。<strong>子shell是嵌在圆括号()内部的命令序列，子Shell内部定义的变量为局部变量。</strong></p>
<p>子shell可用于为一组命令设定临时的环境变量：</p>
<pre><code> COMMAND1
 COMMAND2
 COMMAND3(
   IFS=:
   PATH=/bin  unset TERMINFO  set -C
   shift 5
   COMMAND4
   COMMAND5  exit 3 # 只是从子shell退出。)# 父shell不受影响，变量值没有更改。
 COMMAND6
 COMMAND7
</code></pre>
                
              </div>

              
                <span class="post-meta">
                  
                    #<a href="https://systemime.github.iotags/linux/">Linux</a>&nbsp;
                  
                    #<a href="https://systemime.github.iotags/xargs/">xargs</a>&nbsp;
                  
                </span>
              

            </article>
          
        </div>
        
          <ul class="pager main-pager">
            
              <li class="previous">
                <a href="https://systemime.github.io/series/%E6%9D%82%E6%8A%80%E6%B5%85%E5%B0%9D/page/7">&larr; Newer Posts</a>
              </li>
            
            
              <li class="next">
                <a href="https://systemime.github.io/series/%E6%9D%82%E6%8A%80%E6%B5%85%E5%B0%9D/page/9">Older Posts &rarr;</a>
              </li>
            
          </ul>
        
      </div>
    <div align="center" class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
        

<ul class="pagination">
    
    <li class="page-item">
        <a href="https://systemime.github.io/series/%E6%9D%82%E6%8A%80%E6%B5%85%E5%B0%9D/" class="page-link" aria-label="First"><span aria-hidden="true">&laquo;&laquo;</span></a>
    </li>
    
    <li class="page-item">
    <a href="https://systemime.github.io/series/%E6%9D%82%E6%8A%80%E6%B5%85%E5%B0%9D/page/7/" class="page-link" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a>
    </li>
    
    
    
    
    
    
    
        
        
    
    
    <li class="page-item"><a class="page-link" href="https://systemime.github.io/series/%E6%9D%82%E6%8A%80%E6%B5%85%E5%B0%9D/">1</a></li>
    
    
    
    
    
    
        
        
    
    
    <li class="page-item"><a class="page-link" href="https://systemime.github.io/series/%E6%9D%82%E6%8A%80%E6%B5%85%E5%B0%9D/page/2/">2</a></li>
    
    
    
    
    
    
        
        
    
    
    <li class="page-item"><a class="page-link" href="https://systemime.github.io/series/%E6%9D%82%E6%8A%80%E6%B5%85%E5%B0%9D/page/3/">3</a></li>
    
    
    
    
    
    
        
        
    
    
    <li class="page-item disabled"><span aria-hidden="true">&nbsp;&hellip;&nbsp;</span></li>
    
    
    
    
    
    
        
        
    
    
    
    
    
    
    
        
        
    
    
    
    
    
    
    
        
        
    
    
    <li class="page-item"><a class="page-link" href="https://systemime.github.io/series/%E6%9D%82%E6%8A%80%E6%B5%85%E5%B0%9D/page/7/">7</a></li>
    
    
    
    
    
    
        
        
    
    
    <li class="page-item active"><a class="page-link" href="https://systemime.github.io/series/%E6%9D%82%E6%8A%80%E6%B5%85%E5%B0%9D/page/8/">8</a></li>
    
    
    
    
    
    
        
        
    
    
    <li class="page-item"><a class="page-link" href="https://systemime.github.io/series/%E6%9D%82%E6%8A%80%E6%B5%85%E5%B0%9D/page/9/">9</a></li>
    
    
    
    
    
    
        
        
    
    
    <li class="page-item disabled"><span aria-hidden="true">&nbsp;&hellip;&nbsp;</span></li>
    
    
    
    
    
    
        
        
    
    
    <li class="page-item"><a class="page-link" href="https://systemime.github.io/series/%E6%9D%82%E6%8A%80%E6%B5%85%E5%B0%9D/page/11/">11</a></li>
    
    
    <li class="page-item">
    <a href="https://systemime.github.io/series/%E6%9D%82%E6%8A%80%E6%B5%85%E5%B0%9D/page/9/" class="page-link" aria-label="Next"><span aria-hidden="true">&raquo;</span></a>
    </li>
    
    <li class="page-item">
        <a href="https://systemime.github.io/series/%E6%9D%82%E6%8A%80%E6%B5%85%E5%B0%9D/page/11/" class="page-link" aria-label="Last"><span aria-hidden="true">&raquo;&raquo;</span></a>
    </li>
    
</ul>


        
        
        
        
        
      </div>
    </div>
  </div>

    <div class="rocket"><img src="https://systemime.github.io/img/rocket_up.png" alt="" width="100" height="100"></div>
<script>
    $(function () {
      $(window).scroll(function () {
        
        if ($(window).scrollTop() >= 1000) {
          $('.rocket').stop().fadeIn(1000);
        }else {
          $('.rocket').stop().fadeOut(1000);
        }
      })
      
      $('.rocket').click(function () {
        $('html,body').stop().animate({scrollTop:0},400);
       
      })
    })

</script>

    
    <div id="landlord">
        <div class="message" style="opacity:0"></div>
        <canvas id="live2d" width="280" height="250" class="live2d"></canvas>
        <div class="hide-button">隐藏</div>
    </div>
    
    <footer id="copyright">
  <div class="container">
    <div class="row">
      <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
        <ul class="list-inline text-center footer-links">
          
          
        </ul>
        <p class="credits copyright text-muted">
        &copy;2017-2018
          
          &nbsp;&bull;&nbsp;
          September 20,2019
          updated
          
            &nbsp;&bull;&nbsp;
            <a href="https://systemime.github.io">Home</a>
          
        </p>

        <p class="credits theme-by text-muted">
        <a href="https://servicemesher.github.io" target="_blank">ServiceMesher</a>&nbsp;&bull;&nbsp;<a href="https://github.com/yangchuansheng/k8s-knowledge" target="_blank">Kubernetes 知识图谱</a>
        <br />
        <span id="busuanzi_container_site_pv">
            本站已被访问 <span id="busuanzi_value_site_pv"></span> 次啦
        </span>
        <span id="busuanzi_container_site_uv">
            &ensp;|&ensp;&thinsp;您是第 <span id="busuanzi_value_site_uv"></span> 位到访的小伙伴喔
        </span>
        </p>
        
        <p class="credits theme-by text-muted">
          <a href="http://gohugo.io">Hugo v0.67.0</a> powered &nbsp;&bull;&nbsp; Theme by <a href="http://deanattali.com/beautiful-jekyll/">Beautiful Jekyll</a> adapted to <a href="https://github.com/halogenica/beautifulhugo">Beautiful Hugo</a>
          
          <center><section class="credits theme-by text-muted">
    <span class="footer__copyright">
    <div>
    <span id="span_dt_dt"> </span>
    <script language="javascript">
      function show_date_time(){
        window.setTimeout("show_date_time()", 1000);
        BirthDay=new Date("7/8/2017 10:56:12");
        today=new Date();
        timeold=(today.getTime()-BirthDay.getTime());
        sectimeold=timeold/1000
        secondsold=Math.floor(sectimeold);
        msPerDay=24*60*60*1000
        e_daysold=timeold/msPerDay
        daysold=Math.floor(e_daysold);
        e_hrsold=(e_daysold-daysold)*24;
        hrsold=Math.floor(e_hrsold);
        e_minsold=(e_hrsold-hrsold)*60;
        minsold=Math.floor((e_hrsold-hrsold)*60);
        seconds=Math.floor((e_minsold-minsold)*60);
        span_dt_dt.innerHTML="本博客已经开心运行 "+daysold+" 天 "+hrsold+" 小时 "+minsold+" 分 "+seconds+" 秒";
      }
      show_date_time();
    </script>
    </div>
</script>
</section>
</center>
        </p>
      </div>
    </div>
  </div>
</footer>


<script src="https://res.cloudinary.com/jimmysong/raw/upload/rootsongjc-hugo/bootstrap.min.js"></script>
<script src="https://res.cloudinary.com/jimmysong/raw/upload/rootsongjc-hugo/photoswipe-ui-default.min.js"></script>
<script src="https://res.cloudinary.com/jimmysong/raw/upload/rootsongjc-hugo/photoswipe.min.js"></script>
<script src="https://res.cloudinary.com/jimmysong/raw/upload/rootsongjc-hugo/auto-render.min.js"></script>
<script src="https://systemime.github.io/js/main.js"></script>
<script src="https://systemime.github.io/js/clipboard.min.js"></script>
<script src="https://systemime.github.io/js/prism.js?t=123"></script>
<script src="https://systemime.github.io/js/highlight.min.js"></script>
<script src="https://res.cloudinary.com/jimmysong/raw/upload/rootsongjc-hugo/katex.min.js"></script>
<script src="https://systemime.github.io/js/reward.js"></script>
<script src="https://systemime.github.io/js/canvas_ribbon.js"></script>
<script> renderMathInElement(document.body); </script>

<script src="https://systemime.github.io/js/baguetteBox.js"></script>
<script> baguetteBox.run('.gallery');</script>






<script async defer src="https://buttons.github.io/buttons.js"></script>


<script src="https://polyfill.io/v2/polyfill.min.js?features=IntersectionObserver"></script>
<script type="text/javascript" src="https://systemime.github.io/js/quicklink.umd.js"></script>
<script>
window.addEventListener('load', () =>{
   quicklink();
});
</script>



<script type="text/javascript">
 
var a_idx = 0;
jQuery(document).ready(function($) {
    $("body").click(function(e) {
        var a = new Array("Docker", "Kubernetes", "Prometheus", "Envoy", "Istio", "Service Mesh", "Cloud Native");
        var $i = $("<span />").text(a[a_idx]);
        a_idx = (a_idx + 1) % a.length;
        var x = e.pageX,
        y = e.pageY;
        function randomColor() {
          var flakeColor = new Array("#FFDA65", "#00BFFF", "#BA55D3", "#FFA07A", "#87CEEB", "#FFB6C1");
          var snowColor = flakeColor[Math.floor(flakeColor.length * Math.random())];
          return snowColor;
        }
        $i.css({
            "z-index": 999999999999999999999999999999999999999999999999999999999999999999999,
            "top": y - 20,
            "left": x,
            "position": "absolute",
            "font-weight": "bold",
            "color": randomColor()
        });
        $("body").append($i);
        $i.animate({
            "top": y - 180,
            "opacity": 0
        },
        1500,
        function() {
            $i.remove();
        });
    });
});
</script>


<script type="text/javascript" src="https://systemime.github.io/js/lightbox.js"></script>











<script src="https://cdn.plyr.io/3.4.7/plyr.js"></script>
<script>const player = new Plyr('#player');</script>


<script async defer src="https://buttons.github.io/buttons.js"></script>


  </body>
</html>

